package com.lanhai.zhonglai.dispatch;


import com.google.gson.Gson;
import com.lanhai.zhonglai.MsgCore;
import com.lanhai.zhonglai.beans.*;
import com.lanhai.zhonglai.dao.AgvStateLogBean;
import com.lanhai.zhonglai.enums.AgvCurrentTransEnum;
import com.lanhai.zhonglai.enums.AgvMountTypeEnum;
import com.lanhai.zhonglai.enums.AgvReceiveEnum;
import com.lanhai.zhonglai.enums.DotTypeEnum;
import com.lanhai.zhonglai.enums.TransDirectionEnum;
import com.lanhai.zhonglai.interfaces.*;
import com.lanhai.zhonglai.mapper.TransLogMapper;
import com.lanhai.zhonglai.report.AgvStateMap;
import com.lanhai.zhonglai.third.KSHeartThread;
import com.lanhai.zhonglai.third.StationFactory;
import com.lanhai.zhonglai.utils.DmdUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * 小车的消息处理
 *
 * @author zhengwei
 */

/**
 * @author zhengwei
 */
@EnableAsync
@Service
public class DispatchAgv {


    @Autowired
    IAgv iAgv;

    @Autowired
    IAgvMount iAgvMount;

    @Autowired
    IAgvEvent iAgvEvent;


    @Autowired
    IDot iDot;

    @Autowired
    IDotEvent iDotEvent;

    @Autowired
    IStation iStation;

    @Autowired
    IControlArea iControlArea;


    @Autowired
    ISendData sendTools;

    @Autowired
    ICmdLog iCmdLog;


    @Autowired
    IPower iPower;

    @Autowired
    IRoad iRoad;

    @Autowired
    AgvStateMap stateMap;

    @Autowired
    AgvCmdMap agvCmdMap;

    @Autowired
    KSHeartThread heart;

    @Autowired
    JedisPool jedisPool;

    @Autowired
    private TransLogMapper transLogMapper;


    @Autowired
    JudgmentBSG_3 bsg3;

    @Autowired
    JudgementALD_3 aldgan;

    @Autowired
    JudgementALD_4 aldSi;

    @Autowired
    IStationMount iStationMount;

    @Autowired
    private DmdUtils dmdUtils;


    Gson gson = new Gson();

    private static final Logger logger = LogManager.getLogger("agvlog");


    @Async("agvExecutor")
    public void saveAgvState(AgvDataBean data, String ip) {
        //行驶状态时，不匹配点位
        if (data.getReceiveType() != AgvReceiveEnum.XS) {
            DotBean dot = iDot.getBeanByXY(data.getX(), data.getY());
            data.setPointId(dot != null ? dot.getDotno() : 0);
        }
        //设置当前时间
        data.setTs(System.currentTimeMillis());

        Jedis jd = jedisPool.getResource();
        String json = jd.get("agv_" + data.getAgvId());
        Gson gson = new Gson();
        //保存车辆状态变化及持续时间
        AgvDataBean checkAgvBean = gson.fromJson(json, AgvDataBean.class);
        if (checkAgvBean == null) {
            data.setLastReceive(data.getReceiveType());
            data.setLastChaneTime(System.currentTimeMillis());
        } else if (data.getReceiveType() == checkAgvBean.getReceiveType()) {
            data.setLastReceive(checkAgvBean.getLastReceive());
            data.setLastChaneTime(checkAgvBean.getLastChaneTime());
        } else {//车辆状态变化时
            //小车状态日志入库
            storeStateLog(data, checkAgvBean);
            //更新状态、及变化时间
            data.setLastReceive(data.getReceiveType());
            data.setLastChaneTime(System.currentTimeMillis());
        }
        //缓存当前车辆反馈数据到redis
        jd.set("agv_" + data.getAgvId(), gson.toJson(data));
        jd.close();
    }


    @Async("agvExecutor")
    public void resolve(AgvDataBean data) {

        // System.out.println("DispatchAgv : " + Thread.currentThread().getName() + "   " + UUID.randomUUID().toString());

        AgvBean agv = iAgv.getBean(data.getAgvId());
        if (agv == null) {
            // 对应的小车不存在
            logger.error("小车不存在" + data.getAgvId() + "  cmd=" + data.getCmdStr());
            return;
        }

        DotBean dot = iDot.getBeanByXY(data.getX(), data.getY());

        //优先级高的处理
        if (data.getReceiveType() == AgvReceiveEnum.JT) {

            iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
            //处理机台处AGV急停
            if (dot != null) {
                StationBean custation = iStation.getBeanByDot(dot.getDotno());
                if (custation != null) {

                    agv.setFinishTrans(false);
                    agv.setUpHasTrans(false);
                    agv.setDownHasTrans(false);
                    agv.setTransing(false);
                    iAgv.saveCache(agv);
                    //发送AGV异常
                    IStationProtocol stationEvent = StationFactory.getStation(custation.getCmdSign());
                    if (custation.getCmdSign().equals("HC")) {
                        sendTools.sendHCData(custation.getIp(), custation.getPort(), custation.getLine(), "AGV异常", stationEvent.transError(custation.getLine(), custation.getFillType()), custation.getStationname());
                    } else {
                        sendTools.sendStationData(custation.getIp(), custation.getPort(), custation.getLine(), "AGV异常", stationEvent.transError(custation.getLine(), custation.getFillType()), custation.getStationname());
                    }
                }
            }

            stateMap.saveState(data, agv);
            agvCmdMap.setDispatch(data, false);
            return;
        } else if (data.getReceiveType() == AgvReceiveEnum.TZ || data.getReceiveType() == AgvReceiveEnum.LEAVEDEVICE) {
            iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
            if (data.getReceiveType() == AgvReceiveEnum.TZ) {
                //交管区
                offline(agv, data);

            }

            //处理机台前的停止和手动回退
            if (dot != null && dot.getDotType() == DotTypeEnum.Trans) {
                StationBean custation = iStation.getBeanByDot(dot.getDotno());
                if (custation != null) {

                    IStationProtocol stationEvent = StationFactory.getStation(custation.getCmdSign());
                    if (data.getReceiveType() == AgvReceiveEnum.TZ) {
                        // 停止是异常
                        if (custation.getCmdSign().equals("HC")) {
                            sendTools.sendHCData(custation.getIp(), custation.getPort(), custation.getLine(), "异常",
                                    stationEvent.transError(custation.getLine(), custation.getFillType()),
                                    custation.getStationname());

                        } else {
                            sendTools.sendStationData(custation.getIp(), custation.getPort(), custation.getLine(), "异常",
                                    stationEvent.transError(custation.getLine(), custation.getFillType()),
                                    custation.getStationname());
                        }
                    } else {
                        // 离开
                        if (custation.getCmdSign().equals("HC")) {
                            sendTools.sendHCData(custation.getIp(), custation.getPort(), custation.getLine(), "AGV离开",
                                    stationEvent.agvLeave(custation.getLine(), custation.getFillType()),
                                    custation.getStationname());

                        } else {
                            sendTools.sendStationData(custation.getIp(), custation.getPort(), custation.getLine(),
                                    "AGV离开", stationEvent.agvLeave(custation.getLine(), custation.getFillType()),
                                    custation.getStationname());
                        }

                    }
                }
            } else {
                // 非传输位,重置数据
                agv.setFinishTrans(false);
                agv.setUpHasTrans(false);
                agv.setDownHasTrans(false);
                agv.setTransing(false);
                agv.setCurrentTrans(AgvCurrentTransEnum.None);
                iAgv.saveCache(agv);
            }
            stateMap.saveState(data, agv);
            agvCmdMap.setDispatch(data, false);
            return;
        }


        if (agvCmdMap.isDispatch(agv.getAgvId())) {
            //正在处理中，不操作
            iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
            String msge = String.format("AGV：[%s],正在处理%s，无法处理新的请求:%s", agv.getAgvId(), agv.getCurrentDo(),
                    data.getReceiveType().getName());
            logger.error(msge);
            return;
        }

        agvCmdMap.setDispatch(data, true);

        AgvMountBean mobj = new AgvMountBean();
        mobj.setDownFull(data.isDownFull());
        mobj.setUpFull(data.isUpFull());
        mobj.setMountType(data.getMountType());
        agv.setCurrentDo(data.getReceiveType().getName());

        switch (data.getReceiveType()) {
            case BZ:
                //// 避障 nothing
                break;
            case CD:
                //// 充电 nothing
                break;
            case DD:
                //// 到达
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                arrived(agv, data, mobj, dot);
                break;
            case DM:
                // 待命 nothing
                break;
            case JG:
                // 交管 nothing
                break;
            case KCS:
                // 可传输,发起调度
                if (dot == null) {
                    stateMap.saveState(data, agv);
                    agvCmdMap.setDispatch(data, false);
                    return;
                }
                if (dot.getDotType() == DotTypeEnum.Power) {
                    MsgCore.sendMsg(agv.getAgvId(), "充电中，请勿操作");
                    stateMap.saveState(data, agv);
                    agvCmdMap.setDispatch(data, false);
                    return;
                }

                if (dot.getDotType() != DotTypeEnum.Trans) {
                    stateMap.saveState(data, agv);
                    agvCmdMap.setDispatch(data, false);
                    return;
                }

                if (agv.isTransing() == false) {
                    iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());


                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    // 发起调度
                    noticeJudgement(agv, dot, station, mobj);

                }
                break;
            case LX:
                // 离线
                break;
            case XCC:
                //下层传出中
                //扩散要求传输过程中一直发申请传输的指令
                if (dot != null) {
                    StationBean kstation = iStation.getBeanByDot(dot.getDotno());
                    if (kstation != null && kstation.getCmdSign().equals("KS")) {
                        IStationProtocol stationEvent = StationFactory.getStation(kstation.getCmdSign());
                        byte[] cmd = stationEvent.applyRecieve(kstation.getLine(), kstation.getFillType());
                        // 扩散需要添加心跳
                        cmd[3] = heart.getHeart();
                        sendTools.sendStationData(kstation.getIp(), kstation.getPort(), kstation.getLine(), "AGV申请传输",
                                cmd, kstation.getStationname());
                    }
                }
                break;
            case XCR:
                //下层传入中
                //扩散要求传输过程中一直发申请传输的指令
                if (dot != null) {
                    StationBean kstation2 = iStation.getBeanByDot(dot.getDotno());
                    if (kstation2 != null && kstation2.getCmdSign().equals("KS")) {
                        IStationProtocol stationEvent = StationFactory.getStation(kstation2.getCmdSign());
                        byte[] cmd = stationEvent.applyRecieve(kstation2.getLine(), kstation2.getFillType());
                        //扩散需要添加心跳
                        cmd[3] = heart.getHeart();
                        sendTools.sendStationData(kstation2.getIp(), kstation2.getPort(), kstation2.getLine(), "AGV申请传输", cmd,
                                kstation2.getStationname());
                    }
                }
                break;
            case SCCW:
                //上层传出完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setUpHasTrans(true);
                if (agv.isDownHasTrans()) {
                    agv.setFinishTrans(true);
                }
                agv.setTransing(false);
                iAgv.saveCache(agv);


                if (dot != null) {
                    if (agv.isNotClear() == false) {
                        //不需要清理的标识=false，表示要清理
                        StationCmdMap.stopTrans(dot.getDotno());
                        agv.setCurrentTrans(AgvCurrentTransEnum.None);
                        iAgv.saveCache(agv);
                    }
                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.OnlyIn, AgvReceiveEnum.SCCW);
                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }
                break;
            case SCRW:
                //上层传入完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setUpHasTrans(true);
                if (agv.isDownHasTrans()) {
                    agv.setFinishTrans(true);
                }
                agv.setTransing(false);
                iAgv.saveCache(agv);


                if (dot != null) {
                    if (agv.isNotClear() == false) {
                        //不需要清理的标识=false，表示要清理
                        StationCmdMap.stopTrans(dot.getDotno());
                        agv.setCurrentTrans(AgvCurrentTransEnum.None);
                        iAgv.saveCache(agv);
                    }

                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.OnlyOut, AgvReceiveEnum.SCRW);


                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }
                break;
            case SCXRW:
                //上出下入完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setUpHasTrans(true);
                agv.setDownHasTrans(true);
                agv.setFinishTrans(true);
                agv.setCurrentTrans(AgvCurrentTransEnum.None);
                agv.setTransing(false);
                iAgv.saveCache(agv);


                if (dot != null) {
                    StationCmdMap.stopTrans(dot.getDotno());

                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.Both, AgvReceiveEnum.SCXRW);


                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }
                break;
            case SRXCW:
                //上入下出完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setUpHasTrans(true);
                agv.setDownHasTrans(true);
                agv.setFinishTrans(true);
                agv.setCurrentTrans(AgvCurrentTransEnum.None);
                agv.setTransing(false);


                iAgv.saveCache(agv);

                if (dot != null) {
                    StationCmdMap.stopTrans(dot.getDotno());

                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.Both, AgvReceiveEnum.SRXCW);


                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }
                break;
            case XCCW:
                //下层传出完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setDownHasTrans(true);
                if (agv.isUpHasTrans()) {
                    agv.setFinishTrans(true);
                }
                agv.setTransing(false);
                iAgv.saveCache(agv);


                if (dot != null) {
                    if (agv.isNotClear() == false) {
                        //不需要清理的标识=false，表示要清理
                        StationCmdMap.stopTrans(dot.getDotno());

                        agv.setCurrentTrans(AgvCurrentTransEnum.None);
                        iAgv.saveCache(agv);
                    }

                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.OnlyIn, AgvReceiveEnum.XCCW);

                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }

                break;
            case XCRW:
                //下层传入完成
                iCmdLog.addAgvReceiveLog(data.getAgvId(), data.getReceiveType().getName(), data.getCmdStr());
                agv.setDownHasTrans(true);
                if (agv.isUpHasTrans()) {
                    agv.setFinishTrans(true);
                }
                agv.setTransing(false);
                iAgv.saveCache(agv);


                if (dot != null) {
                    if (agv.isNotClear() == false) {
                        //不需要清理的标识=false，表示要清理
                        StationCmdMap.stopTrans(dot.getDotno());
                        agv.setCurrentTrans(AgvCurrentTransEnum.None);
                        iAgv.saveCache(agv);
                    }
                    StationBean station = iStation.getBeanByDot(dot.getDotno());
                    iCmdLog.saveTransLogOnce(agv, station, TransDirectionEnum.OnlyOut, AgvReceiveEnum.XCRW);

                    //调度
                    noticeJudgement(agv, dot, station, mobj);
                }
                break;
            case ZXWC:
                // 装卸完成 nothing
                break;
            case ERR:
                // 异常了
                break;
            case XS:
                // 行驶中

                moving(agv, data);
                break;
            case XZC:
                //下左传出
                break;
            case XRC:
                //下右传出
                break;
            case XZCW:
                //下左传出完成
                break;
            case XRCW:
                //下右传出完成

                break;
            default:
                break;
        }


        stateMap.saveState(data, agv);
        agvCmdMap.setDispatch(data, false);
    }

    /**
     * 发起调度判断（普通点）
     */
    void noticeJudgement(AgvBean agv, DotBean bean, StationBean station, AgvMountBean mobj) {
        if (mobj.getMountType() == AgvMountTypeEnum.Error) {
            //错误的装料状态，不发起调度判断
            System.out.println("错误的装料状态，不发起调度判断");
            return;
        }

        if (station != null) {
            if (station.getCmdSign().equals("HC")) {
                // 缓存站的处理
                iAgvMount.judgement_HC(agv, station, bean, mobj);
            } else if (station.getCmdSign().equals("POPAID")) {
                // POPAID
                iAgvMount.judgement(agv, station, bean, mobj);
            } else if (agv.getAgvId() == 19 || agv.getAgvId() == 20) {
                // 发料上车 ，同时传
                if (station.getCmdSign().equals("ZRS")) {
                    iAgvMount.judgement_double_toZR(agv, station, bean, mobj);
                } else {
                    iAgvMount.judgement_double(agv, station, bean, mobj);
                }
            } else if (station.getCmdSign().equals("BSG")) {
                StationMountBean dmount = iStationMount.getBean(station.getDotno());
                bsg3.judgement(agv, station, bean, mobj, dmount);


            } else if (station.getCmdSign().equals("SW")
                    || station.getProcess().equals("ALD湿法")) {
                StationMountBean dmount = iStationMount.getBean(station.getDotno());
                aldSi.judgement(agv, station, bean, mobj, dmount);

            } else if (station.getProcess().equals("ALD干法")) {
                StationMountBean dmount = iStationMount.getBean(station.getDotno());
                aldgan.judgement(agv, station, bean, mobj, dmount);
            } else {
                // 传输机台的处理
                iAgvMount.judgement(agv, station, bean, mobj);
            }
        } else {
            MsgCore.sendMsg(agv.getAgvId(), "错误的对接工位，该工位没配设备");
            logger.info(agv.getAgvId() + "  错误的对接工位，该工位没配设备 " + bean.getDotno());
        }
    }


    void moving(AgvBean agv, AgvDataBean data) {
        boolean needsave = false; //需要保存标识


        long areaID = iControlArea.getAreaId(data.getX(), data.getY());
        if (areaID > 0) {
            if (agv.getAreaId() == areaID) {
                //小车自身锁区域，不处理
                if (needsave) {
                    iAgv.saveCache(agv);
                }
                return;
            }
            if (agv.getAreaId() > 0 && agv.getAreaId() != areaID) {
                //从一个区离开极短时间到另外一个区，需要释放原区
                iControlArea.unlockArea(agv.getAreaId());
            }

            // 进入交管区
            agv.setAreaId(areaID);
            iAgv.saveCache(agv);

            if (iControlArea.lockArea(areaID, agv.getAgvId())) {
                // 锁住区域成功,更新当前区域id  继续前进
                return;
            } else {
                // 不能通行，需要停下来
                if (iControlArea.addStopAgv(areaID, agv.getAgvId())) {
                    // 向小车发送停车的指令
                    iAgvEvent.stopOrstart(agv, true);
                }
            }
        } else {
            // 离开交管区
            if (agv.getAreaId() > 0) {
                iControlArea.unlockArea(agv.getAreaId());
                if (agv.getNexttStationName() != null && agv.getNexttStationName().equals("") == false) {
                    MsgCore.sendMsg(agv.getAgvId(), "目标机台：" + agv.getNexttStationName());
                } else {
                    MsgCore.sendMsg(agv.getAgvId(), "寻找可用的机台");
                }
                agv.setAreaId(0);
                needsave = true;
            }
            if (needsave) {
                iAgv.saveCache(agv);
            }
        }
    }

    void arrived(AgvBean agv, AgvDataBean data, AgvMountBean mobj, DotBean cDot) {
        //清除除开到达待命点以外的待命点缓存
        if (cDot.getDotType() != DotTypeEnum.Wait) {
            dmdUtils.clearDmdChech(agv.getAgvId()+"");
        }

        // 位置没变化才操作
        // 更新小车信息
        agv.setCurrentX(data.getX());
        agv.setCurrentY(data.getY());
        agv.setPower(data.getPower());
        if (cDot == null) {
            // 到达了一个表中不存在的停泊位，这是一个数据BUG
            MsgCore.sendMsg(agv.getAgvId(), String.format("AGV到达了一个错误的点位:X=%d,Y=%d", data.getX(), data.getY()));
            return;
        }


        agv.setDotno(cDot.getDotno());
        agv.setFinishTrans(false);
        agv.setUpHasTrans(false);
        agv.setDownHasTrans(false);
        agv.setCurrentTrans(AgvCurrentTransEnum.None);
        iAgv.saveCache(agv);


        //// 开始处理停泊位的各种类型
        if (cDot.getDotType() == DotTypeEnum.Power) {
            //// 充电点
            MsgCore.sendMsg(agv.getAgvId(), "开始充电");
            iDotEvent.arrivedPower(agv, cDot);
            agv.setNexttStationName("");
            agv.setNextRoad(0);
            iAgv.saveCache(agv);
            iPower.agvArrivedPower(agv.getAgvId(), cDot.getDotno());
        } else if (cDot.getDotType() == DotTypeEnum.Wait) {
            //// 待命点
            MsgCore.sendMsg(agv.getAgvId(), "待命中，目标工序：" + agv.getNextProcess());
            iDotEvent.arrivedWait(agv, data, cDot);

        } else if (cDot.getDotType() == DotTypeEnum.Trans) {
            //// 可传输工位
            iDotEvent.arrivedTrans(agv, cDot);

            //放辆充电的小车
            iPower.agvBackToWork();
        } else if (cDot.getDotType() == DotTypeEnum.Decide) {
            ////决策点
            iDotEvent.arrivedDecide(agv, cDot, data);
        } else if (cDot.getDotType() == DotTypeEnum.Route) {
            //路由点，直接行始小车
            iDotEvent.arrivedRoute(agv, cDot);
        } else if (cDot.getDotType() == DotTypeEnum.QrBefore) {
            //先给机台发离开的消息
            int transdot = iDot.getTransDotNo(cDot.getDotno());
            StationBean custation = iStation.getBeanByDot(transdot);
            if (custation != null) {
                //发送AGV异常
                IStationProtocol stationEvent = StationFactory.getStation(custation.getCmdSign());
                if (custation.getCmdSign().equals("HC")) {
                    sendTools.sendHCData(custation.getIp(), custation.getPort(), custation.getLine(), "AGV已离开",
                            stationEvent.agvLeave(custation.getLine(), custation.getFillType()),
                            custation.getStationname());
                } else {
                    sendTools.sendStationData(custation.getIp(), custation.getPort(), custation.getLine(), "AGV已离开",
                            stationEvent.agvLeave(custation.getLine(), custation.getFillType()),
                            custation.getStationname());
                }
                // 重置机台传输数据
                StationCmdMap.clearState(custation.getDotno());
            }

            if (mobj.getMountType() == AgvMountTypeEnum.Error) {
                //错误的装卸情况，比如上X下空，上满下X，不处理
                MsgCore.sendMsg(agv.getAgvId(), "花篮数量异常，暂停");
                return;
            }


            //再处理二维码的事
            if (agv.isFinishTrans()) {
                //传输完成到达QR，在QR处释放
                iDotEvent.arrivedQR(agv, cDot);
            } else {
                //AGV没有完成传输就退回了二维码
                iDotEvent.arrivedQRWithNoTrans(agv, cDot, mobj, transdot);
            }
        } else if (cDot.getDotType() == DotTypeEnum.Normal) {
            //普通点位，按需求处理
            iDotEvent.arrivedNormal(agv, cDot);
        } else if (cDot.getDotType() == DotTypeEnum.PowerCheck) {
            //电量判断
            iDotEvent.arrivedPowerCheck(agv, data, cDot);
        }
    }


    /**
     * AGV离线，手动控制中
     *
     * @param agv
     */
    void offline(AgvBean agv, AgvDataBean data) {
        if (agv.getAreaId() > 0) {
            //如果有交管区
            long areaID = iControlArea.getAreaId(data.getX(), data.getY());
            if (areaID == 0 || agv.getAreaId() != areaID) {
                //离开了事发的交管区,需要处理之前的交管
                areaID = agv.getAreaId();
                agv.setAreaId(0);
                iAgv.saveCache(agv);
                iControlArea.removeStopAgv(areaID, agv.getAgvId());
            }
        }

    }


    /**
     * 组装agv状态日志
     */
    void storeStateLog(AgvDataBean agvdata, AgvDataBean checkAgvBean) {

        long now = System.currentTimeMillis();
        //组装入库对象
        AgvStateLogBean agvStateLogBean = new AgvStateLogBean();
        agvStateLogBean.setAgv_id(agvdata.getAgvId());
        agvStateLogBean.setState(agvdata.getReceiveType().getCode());
        agvStateLogBean.setDuration(now - checkAgvBean.getLastChaneTime());
        agvStateLogBean.setStep("0");

        if (0 != agvdata.getPointId()) {
            agvStateLogBean.setPoint_id(agvdata.getPointId());

            //通过点位获取机台信息
            StationBean custation = iStation.getBeanByDot(agvdata.getPointId());
            if (custation != null) {
                agvStateLogBean.setStation_ip(custation.getIp());
            }
        }

        //外层会更新缓存数据 需要修改返回小车的状态更新时间
        saveLogBean(agvStateLogBean);
    }

    @Async("agvExecutor")
    void saveLogBean(AgvStateLogBean bean) {
        transLogMapper.addStateLog(bean);
    }
}
